﻿using System;
using BasicFramework.Components;
using BasicFramework.Devices.DirectX9;
using BasicFramework.Services;
using BasicFramework.Services.Graphics;
using BasicFrameworkComponentLibrary.GeneralComponents.InputComponents;
using SlimDX;
using SlimDX.Direct3D9;

namespace BasicFrameworkComponentLibrary.DirectX9.Components.Cameras
{
    [ComponentDependency(typeof(Transform), typeof(InputReceiver))]
    public class FixedCamera : Component
    {

        #region Fields

        private Transform transform;

        private Vector3 lookAt = Vector3.Zero;
        private Vector3 up = new Vector3(0, 1, 0);

        private float near = 0.1f;
        private float far = 1000.0f;
        private float fieldOfView = (float)Math.PI / 4;
        private float aspectRatio;
        private IGraphicsService<DX9DeviceContext> graphicsService;



        #endregion


        #region Properties


        public Vector3 LookAt
        {
            get
            {
                return this.lookAt;
            }
            set
            {
                this.lookAt = value;
            }
        }

        public Vector3 Up
        {
            get
            {
                return this.up;
            }
            set
            {
                this.up = value;
            }
        }



        public Vector3 EyePosition
        {
            get
            {
                return this.transform.Position;
            }
            set
            {
                this.transform.Position = value;
            }
        }

        public float Near
        {
            get
            {
                return near;
            }
            set
            {
                near = value;
            }
        }

        public float Far
        {
            get
            {
                return far;
            }
            set
            {
                far = value;
            }
        }

        public float FieldOfView
        {
            get
            {
                return fieldOfView;
            }
            set
            {
                fieldOfView = value;
            }
        }



        public float AspectRatio
        {
            get
            {
                return aspectRatio;
            }
            set
            {
                if (this.aspectRatio != value)
                {
                    this.aspectRatio = value;
                }
            }
        }

        #endregion


        #region Constructors
        #endregion


        #region Events


        #endregion


        #region Methods

        public override void Initialize(bool addDependencies)
        {
            base.Initialize(addDependencies);

            this.graphicsService = ServiceProvider.GetService<IGraphicsService<DX9DeviceContext>>();

            aspectRatio = (float)4 / (float)3;
            this.transform = Owner.Find<Transform>();

        }
        public override void Start()
        {
            base.Start();

            //this.transform.Position = new Vector3(0, 0, -1);
        }

        public override void Update(float frame)
        {
            base.Update(frame);
            if (this.graphicsService != null)
            {
                this.graphicsService.DeviceContext.Device.SetTransform(TransformState.Projection,
                                    Matrix.PerspectiveFovLH(this.fieldOfView, this.aspectRatio, this.near, this.far));

                this.graphicsService.DeviceContext.Device.SetTransform(TransformState.View,
                                    Matrix.LookAtLH(this.EyePosition, this.lookAt, new Vector3(0, 1, 0)));
            }
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }

        public void ResetCamera()
        {
            this.LookAt = new Vector3(0);
            this.Up = new Vector3(0, 1, 0);
            this.EyePosition = new Vector3(0, 0, -1);

        }

        public override void UnloadResources(bool unloadAllContent)
        {
            base.UnloadResources(unloadAllContent);
        }

        #endregion


    }
}
